package sbc.corso;

import java.util.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

import sbc.corso.shareable.Platine;
import sbc.corso.shareable.PlatinenFabrikInfo;
import sbc.corso.shareable.Sensor;
import corso.lang.CorsoConnection;
import corso.lang.CorsoDataException;
import corso.lang.CorsoNotification;
import corso.lang.CorsoNotificationItem;
import corso.lang.CorsoReadException;
import corso.lang.CorsoStrategy;
import corso.lang.CorsoTimeoutException;
import corso.lang.CorsoVarOid;

public class Montage {
	
	public Montage(String mtid) {
 		
		/*
		 * connect to Corso and
		 * get or create PlatinenFabrikInfo
		 */
		System.out.println("Montage gestartet.");
		CorsoConnection con = CorsoUtil.getCorsoConnection();
		PlatinenFabrikInfo fabrik = CorsoUtil.getPlatinenFabrikInfo(con);
		
		/*
		 * read various Oids
		 */
    	Vector platinenOids = fabrik.getPlatinenOids();
    	Vector sensorenOids = fabrik.getSensorenOids();
    	CorsoVarOid platinenOid = fabrik.getPlatinenOid();
    	CorsoVarOid sensorenOid = fabrik.getSensorenOid();
    	
    	CorsoVarOid newFiredOid;
    	
    	
		//System.out.println ("Starte Notification");

        Vector vect = new Vector ();
	    try	{
	    	/*
	    	 * Add Notifications for Platinen- and SensorenOid
	    	 */
			CorsoNotificationItem platinenNotifItem = new CorsoNotificationItem (
										platinenOid, 
										0, 
										CorsoNotificationItem.CURRENT_TIMESTAMP); 
			vect.add(platinenNotifItem);				
			//System.out.println ("Notification for Platinen " + platinenOid + " added");
			
			CorsoNotificationItem sensorenNotifItem = new CorsoNotificationItem (
									sensorenOid, 
									0, 
									CorsoNotificationItem.CURRENT_TIMESTAMP); 
			vect.add(sensorenNotifItem);				
			//System.out.println ("Notification for Sensoren " + sensorenOid + " added");
			
	    	/*
	    	 * create notifications for all PlatineOids
	    	 */
			//System.out.println("platinenOids.size(): " + platinenOids.size());
			for (int i = 0; i < platinenOids.size(); i++) {
	    		CorsoVarOid pOid = (CorsoVarOid)platinenOids.get(i);
				CorsoNotificationItem platineNotifItem = new CorsoNotificationItem (
											pOid, 
											0, 
											CorsoNotificationItem.CURRENT_TIMESTAMP); 
				vect.add(platineNotifItem);				
				//System.out.println ("Notification for Platine " + pOid + " added");
			}
			
	    	/*
	    	 * create notifications for all SensorOids
	    	 */		
			//System.out.println("sensorenOids.size(): " + sensorenOids.size());
			for (int i = 0; i < sensorenOids.size(); i++) {
	    		CorsoVarOid sOid = (CorsoVarOid)sensorenOids.get(i);
		        CorsoNotificationItem sensorNotifItem = new CorsoNotificationItem (
		    								sOid, 
											0, 
											CorsoNotificationItem.CURRENT_TIMESTAMP); 
		        vect.add(sensorNotifItem);
				//System.out.println ("Notification for Sensor " + sOid + " added");
			}	        

	        CorsoNotification notification = con.createNotification(vect, new CorsoStrategy (CorsoUtil.STRATEGY));
		
	        
		    /*
		     * start notification and wait until oid is written
		     */ 
		    for (;;) { 

				//System.out.println ("waiting until oid is written"); 
				CorsoNotificationItem fired = notification.start(CorsoConnection.INFINITE_TIMEOUT, null);
				
				/*
				 * try Montage, if possible
				 */
				if (fired != null) { 
					CorsoVarOid firedOid = fired.varOid ();
			    	//System.out.println("firedOid: " + firedOid.toString());
			    	
			    	/*
			    	 * check if firedOid is Platinen- or SensorenOid
			    	 * (this one is fired if a Platine/Sensor was added/removed)
			    	 */
			    	if (firedOid.compareTo(platinenOid) == 0) {
				    	//System.out.println("PlatinenOid fired: " + platinenOid);
				    	// PlatinenOids neu einlesen
				    	platinenOids = fabrik.getPlatinenOids();

				    	/*
				    	 * create notification for new Platine
				    	 */
				    	//System.out.println("platinoids.size()" + platinenOids.size());
						for (int i = 0; i < platinenOids.size(); i++) {
				    		CorsoVarOid pOid = (CorsoVarOid)platinenOids.get(i);
							CorsoNotificationItem platineNotifItem = new CorsoNotificationItem (
														pOid, 
														0, 
														CorsoNotificationItem.CURRENT_TIMESTAMP); 
							if (!vect.contains(platineNotifItem))	{
								vect.add(platineNotifItem);	
								//System.out.println("new_platinenoid: " + pOid);
								firedOid = pOid;
							}
							//System.out.println ("Notification for Platine " + pOid + " added");
						}
				    	
			    	}
			    	if (firedOid.compareTo(sensorenOid) == 0) {
				    	//System.out.println("SensorenOid fired: " + sensorenOid);
				    	// SensorenOids neu einlesen
				    	sensorenOids = fabrik.getSensorenOids();
				    	/*
				    	 * create notification for new Sensor
				    	 */
				    	//System.out.println("sensorenoids.size()" + sensorenOids.size());
						for (int i = 0; i < sensorenOids.size(); i++) {
				    		CorsoVarOid pOid = (CorsoVarOid)sensorenOids.get(i);
							CorsoNotificationItem sensorNotifItem = new CorsoNotificationItem (
														pOid, 
														0, 
														CorsoNotificationItem.CURRENT_TIMESTAMP); 
							if (!vect.contains(sensorNotifItem))	{
								vect.add(sensorNotifItem);	
								//System.out.println("new_sensorenoid: " + pOid);
								firedOid = pOid;
							}
							//System.out.println ("Notification for Sensor " + pOid + " added");
						}
			    	}
			    	
			    	//System.out.println("Sensoren werden auf Platinen montiert:");			    	

			    	
			    	/*
			    	 * get Sensor OR Platine Object from firedOid
			    	 */
			    	Sensor sensor = null;
			    	Platine platine = null;
			    	for (int i = 0; i < platinenOids.size(); i++) {
			    		CorsoVarOid pOid = (CorsoVarOid)platinenOids.get(i);
			    		if ((firedOid.compareTo(pOid) == 0)) {
			    			//System.out.println("firedOid: " + firedOid);
			    			platine = new Platine(firedOid);
			    			/*System.out.println("platine." + platine.getId());
			    			System.out.println("platine." + platine.getStatus());
			    			System.out.println("platine." + platine.getFirstSensor());
			    			System.out.println("Platine fired: " + pOid);
			    			*/
			    		}
			    		else {
			    			//System.out.println("Platine NOT fired: " + pOid);			    			
			    		}			    		
			    	}

			    	for (int i = 0; i < sensorenOids.size(); i++) {
			    		CorsoVarOid sOid = (CorsoVarOid)sensorenOids.get(i);
			    		if (firedOid.compareTo(sOid) == 0) {
			    			//System.out.println("hiiiiiiiiiieeeeeeeeerrrrrrr");
			    			sensor = new Sensor(firedOid);
			    			//System.out.println("Sensor fired: " + sOid);
			    		}
			    		else {
			    			//System.out.println("Sensor NOT fired: " + sOid);			    			
			    		}			    		
			    	}
			    	
			    	
			    	/*
			    	 * look for a Platine for Montage for the fired Sensor
			    	 */	
			    	if (sensor != null ) {					
						/*
						 * read all platinen stored in space
						 * check if they are NICHT_MONTIERT
						 */	
			    		/*
			            System.out.println("id: " + sensor.getId());
			            System.out.println("tm: " + sensor.getTemperaturMessung());
			            System.out.println("hm: " + sensor.getHelligkeitsmessung());
			            System.out.println("fm: " + sensor.getFeuchtigkeitsmessung());
			            */
			    		
			            //System.out.println("hier0");
			            for (int i = 0; i < platinenOids.size();i++)	{
			            	//System.out.println("hier1" + platinenOids.size());
			            	if (sensor.getStatus().equalsIgnoreCase(CorsoUtil.NICHT_MONTIERT))	{
			            		
			            		/*System.out.println("hier2");
			            		
			            		System.out.println("ft" + sensor.getFeuchtigkeitsmessung());
			            		System.out.println("hl" + sensor.getHelligkeitsmessung());
			            		System.out.println("tm" + sensor.getTemperaturMessung());
			            		System.out.println("status" + sensor.getStatus());
			            		*/
			            		
			    				if ( (sensor.getFeuchtigkeitsmessung().equalsIgnoreCase(CorsoUtil.WIRD_GEMESSEN_UND_SCHON_GEPRUEFT) || sensor.getFeuchtigkeitsmessung().equalsIgnoreCase(CorsoUtil.WIRD_NICHT_GEMESSEN))
					    				&& 	(sensor.getHelligkeitsmessung().equalsIgnoreCase(CorsoUtil.WIRD_GEMESSEN_UND_SCHON_GEPRUEFT) || sensor.getHelligkeitsmessung().equalsIgnoreCase(CorsoUtil.WIRD_NICHT_GEMESSEN))
					    				&& (sensor.getTemperaturMessung().equalsIgnoreCase(CorsoUtil.WIRD_GEMESSEN_UND_SCHON_GEPRUEFT) || sensor.getTemperaturMessung().equalsIgnoreCase(CorsoUtil.WIRD_NICHT_GEMESSEN))
					    				&& (sensor.getStatus().equalsIgnoreCase(CorsoUtil.NICHT_MONTIERT)))	{

			    				//	System.out.println("hier3 " + i);
			            		CorsoVarOid platineOid = (CorsoVarOid)platinenOids.get(i);
			            		//System.out.println("platineOid: " + platineOid);
			            		Platine p = new Platine(platineOid);
			            		
			            		//System.out.println("p.status" + p.getStatus());
			            		
			            		if (p.getStatus().equalsIgnoreCase(CorsoUtil.HALB_MONTIERT))	{
		    						p.setSecondSensor(firedOid.toString());
		    						p.setStatus(CorsoUtil.MONTIERT);	
		    						sensor.setStatus(CorsoUtil.MONTIERT);
		    						firedOid.writeShareable(sensor, CorsoConnection.INFINITE_TIMEOUT);
					        		Date datumHeute = new Date();
					        		SimpleDateFormat myDateFormat = new SimpleDateFormat("dd.MM.yyyy, HH:mm:ss");
					        		p.setFertigmontiertam(myDateFormat.format(datumHeute));
					        		p.setFertigmontiertvon(mtid);
		    						platineOid.writeShareable(p, CorsoConnection.INFINITE_TIMEOUT);
		    						
		    						System.out.println("Sensor " + sensor.getId() + " (Oid: " + firedOid + ") wurde als 2. Sensor auf Platine " + p.getId() + " (OID: " + platineOid + ") montiert.");

			            		}
			            		if (p.getStatus().equalsIgnoreCase(CorsoUtil.NICHT_MONTIERT))	{
		    						p.setFirstSensor(firedOid.toString());
		    						p.setStatus(CorsoUtil.HALB_MONTIERT);	
		    						sensor.setStatus(CorsoUtil.MONTIERT);
		    						firedOid.writeShareable(sensor, CorsoConnection.INFINITE_TIMEOUT);
					        		Date datumHeute = new Date();
					        		SimpleDateFormat myDateFormat = new SimpleDateFormat("dd.MM.yyyy, HH:mm:ss");
					        		p.setFertigmontiertam(myDateFormat.format(datumHeute));
					        		p.setFertigmontiertvon(mtid);
		    						platineOid.writeShareable(p, CorsoConnection.INFINITE_TIMEOUT);
		    						System.out.println("Sensor " + sensor.getId() + " (Oid: " + firedOid + ") wurde als 1. Sensor auf Platine " + p.getId() + " (OID: " + platineOid + ") montiert.");
			            		}
			            		
			            	}
			            	}
			      
					    }

			    	}					

			    	
			    	/*
			    	 * look for a Sensor for Montage for the fired Platine
			    	 */		
			    	if (platine != null) {
			    		
			    		for (int i = 0; i < sensorenOids.size();i++)	{
			    		
			    			if ((platine.getStatus().equalsIgnoreCase(CorsoUtil.HALB_MONTIERT)) || (platine.getStatus().equalsIgnoreCase(CorsoUtil.NICHT_MONTIERT)))	{
			    			
			    			
			    				CorsoVarOid sensorOid = (CorsoVarOid)sensorenOids.get(i);
			    				Sensor s = new Sensor(sensorOid);
			    				
			    				if ( (s.getFeuchtigkeitsmessung().equalsIgnoreCase(CorsoUtil.WIRD_GEMESSEN_UND_SCHON_GEPRUEFT) || s.getFeuchtigkeitsmessung().equalsIgnoreCase(CorsoUtil.WIRD_NICHT_GEMESSEN))
			    				&& 	(s.getHelligkeitsmessung().equalsIgnoreCase(CorsoUtil.WIRD_GEMESSEN_UND_SCHON_GEPRUEFT) || s.getHelligkeitsmessung().equalsIgnoreCase(CorsoUtil.WIRD_NICHT_GEMESSEN))
			    				&& (s.getTemperaturMessung().equalsIgnoreCase(CorsoUtil.WIRD_GEMESSEN_UND_SCHON_GEPRUEFT) || s.getTemperaturMessung().equalsIgnoreCase(CorsoUtil.WIRD_NICHT_GEMESSEN))
			    				&& s.getStatus().equalsIgnoreCase(CorsoUtil.NICHT_MONTIERT))	{
			    					
			    					if (platine.getStatus().equalsIgnoreCase(CorsoUtil.NICHT_MONTIERT))	{				
			    						platine.setFirstSensor(sensorOid.toString());
			    						platine.setStatus(CorsoUtil.HALB_MONTIERT);
			    						//System.out.println("Der Sensor mit der Oid" + sensorOid + "wurde als 1. Sensor auf Platine " + firedOid + "montiert.");
			    						System.out.println("Sensor " + s.getId() + " (Oid: " + sensorOid + ") wurde als 1. Sensor auf Platine " + platine.getId() + " (OID: " + firedOid + ") montiert.");
			    					}
			    					else if (platine.getStatus().equalsIgnoreCase(CorsoUtil.HALB_MONTIERT))	{
			    						platine.setSecondSensor(sensorOid.toString());
			    						platine.setStatus(CorsoUtil.MONTIERT);	
			    						//.out.println("Der Sensor mit der Oid" + sensorOid + "wurde als 2. Sensor auf Platine " + firedOid + "montiert.");
			    						System.out.println("Sensor " + s.getId() + " (Oid: " + sensorOid + ") wurde als 2. Sensor auf Platine " + platine.getId() + " (OID: " + firedOid + ") montiert.");
			    					}
					        		Date datumHeute = new Date();
					        		SimpleDateFormat myDateFormat = new SimpleDateFormat("dd.MM.yyyy, HH:mm:ss");
					        		platine.setFertigmontiertam(myDateFormat.format(datumHeute));
					        		platine.setFertigmontiertvon(mtid);
					        		//System.out.println("arsch: " + platine.getFertigmontiertam() + " " + platine.getFertigmontiertvon());
			    					firedOid.writeShareable(platine, CorsoConnection.INFINITE_TIMEOUT);
			    					s.setStatus(CorsoUtil.MONTIERT);
			    					sensorOid.writeShareable (s, CorsoConnection.INFINITE_TIMEOUT);		
			    				}
			    				
			    			}
			    			
			    		}
			    	}

				}
		    }
	    }
		catch (CorsoDataException cde) {
			System.out.println("caught CorsoDataException: " + cde);
		}
		catch (CorsoReadException cre) {
			System.out.println("caught CorsoReadException: " + cre);
		}
		catch (CorsoTimeoutException cte) {
			System.out.println("caught CorsoTimeoutException: " + cte);
		}
		catch (Exception e) {
			System.out.println("caught Exception: " + e);
			e.printStackTrace();
		}
	}	
	
	public static void main(String args[]){
		new Montage(args[2]);
	}	 
}	 

	
	
